package com.example.demo.service;

import com.example.demo.converter.ClothConverter;
import com.example.demo.converter.PostConverter;
import com.example.demo.dao.Cloth;
import com.example.demo.dao.Post;
import com.example.demo.dao.PostRepository;
import com.example.demo.dto.ClothDTO;
import com.example.demo.dto.PostDTO;
import org.hibernate.service.spi.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.awt.*;
import java.io.IOException;
import java.util.List;
import java.util.Set;

@Service
public class PostServiceImpl implements PostService {
    @Autowired
    private PostRepository postRepository;
    @Autowired
    private UserService userService;
    @Autowired
    private ImageService imageService;

    @Override
    public PostDTO getPostById(long id) {
        Post post = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found"));
        try {
            PostDTO postDTO = PostConverter.convertPost(post);
            String imageName = postDTO.getImageName(); // 假设 ClothDTO 中有 getImageName 方法
            if (imageName != null && !imageName.isEmpty()) {
                byte[] imageBytes = imageService.getImageAsBytes(imageName);
                postDTO.setImageBytes(imageBytes); // 假设 ClothDTO 有 setImageBytes 方法
            }
            return postDTO;
        } catch (IOException e) {
            throw new ServiceException("Error retrieving image for Cloth", e);
        } catch (Exception e) {
            throw new ServiceException("Error converting Cloth to ClothDTO", e);
        }
    }

    @Override
    public List<PostDTO> getAll() {
        try {
            List<Post> posts = postRepository.findAll();
            List<PostDTO> postDTOS = PostConverter.convertPostListToPostDTOList(posts);

            for (PostDTO postDTO : postDTOS) {
                String imageName = postDTO.getImageName();
                if (imageName != null && !imageName.isEmpty()) {
                    byte[] imageBytes = imageService.getImageAsBytes(imageName);
                    postDTO.setImageBytes(imageBytes);
                }
            }
            return postDTOS;
        } catch (IOException e) {
            throw new ServiceException("Error retrieving image for Cloth", e);
        } catch (Exception e) {
            throw new ServiceException("Error converting Cloth to ClothDTO", e);
        }
    }

    @Override
    public Set<PostDTO> getPostByUserId(long userId) {
        try {
            Set<Post> posts = postRepository.findByUserId(userId);
            Set<PostDTO> postDTOS = PostConverter.convertToPostDTOSet(posts);

            for (PostDTO postDTO : postDTOS) {
                String imageName = postDTO.getImageName();
                if (imageName != null && !imageName.isEmpty()) {
                    byte[] imageBytes = imageService.getImageAsBytes(imageName);
                    postDTO.setImageBytes(imageBytes);
                }
            }
            return postDTOS;
        } catch (IOException e) {
            throw new ServiceException("Error retrieving image for Cloth", e);
        } catch (Exception e) {
            throw new ServiceException("Error converting Cloth to ClothDTO", e);
        }
    }

    @Override
    public Set<PostDTO> getPostByTitle(String title) {
        try {
            Set<Post> posts = postRepository.findByTitle(title);
            Set<PostDTO> postDTOS = PostConverter.convertToPostDTOSet(posts);
            for (PostDTO postDTO : postDTOS) {
                String imageName = postDTO.getImageName();
                if (imageName != null && !imageName.isEmpty()) {
                    byte[] imageBytes = imageService.getImageAsBytes(imageName);
                    postDTO.setImageBytes(imageBytes);
                }
            }
            return postDTOS;
        } catch (IOException e) {
            throw new ServiceException("Error retrieving image for Cloth", e);
        } catch (Exception e) {
            throw new ServiceException("Error converting Cloth to ClothDTO", e);
        }
    }

    @Override
    public Long addNewPostByUserId(PostDTO postDTO, long userId) {
        postDTO.setUserDTO(userService.getUserById(userId));
        Post post = PostConverter.convertPost(postDTO);
        postRepository.save(post);
        return post.getId();
    }

    @Override
    public void deletePostById(long id) {
        Post post = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found"));
        postRepository.deleteById(id);
    }

    @Override
    public PostDTO updatePostByIdAndUserId(String title, String content, String publicationDate, long id, long userId, int likesCount, int commentsCount, int sharesCount, int favoritesCount) {
        Post postInDB = postRepository.findById(id).orElseThrow(() -> new RuntimeException("Post not found"));
        if (StringUtils.hasLength(content) && !content.equals(postInDB.getContent())) {
            postInDB.setContent(content);
        }
        if (StringUtils.hasLength(title) && !title.equals(postInDB.getTitle())) {
            postInDB.setTitle(title);
        }
        if (likesCount != postInDB.getLikesCount()) {
            postInDB.setLikesCount(likesCount);
        }
        if (commentsCount != postInDB.getCommentsCount()) {
            postInDB.setCommentsCount(commentsCount);
        }
        if (sharesCount != postInDB.getSharesCount()) {
            postInDB.setSharesCount(sharesCount);
        }
        if (favoritesCount != postInDB.getFavoritesCount()) {
            postInDB.setFavoritesCount(favoritesCount);
        }
        return PostConverter.convertPost(postRepository.save(postInDB));
    }
}
